from rest_framework.viewsets import ViewSet, GenericViewSet
from utils.common_view import CommonListModelMixin, CommonRetrieveModelMixin, CommonDestroyModelMixin, \
    CommonCreateModelMixin, CommonUpdateModelMixin
from .models import IDC, ServerGroup, Credential, OtherMachine, NetWorkServer, PhysicalServer, VirtualServer
from .serializer import IDCSerializer, ServerGroupSerializer, CredentialSerializer, OtherMachineSerializer, \
    NetWorkServerSerializer, PhysicalServerSerializer
from user.authentication import LoginAuthentication
from utils.common_pagination import PageNumberPagination
from rest_framework.decorators import action


# IDC 增删查改
class IDCView(GenericViewSet, CommonListModelMixin, CommonRetrieveModelMixin, CommonDestroyModelMixin,
              CommonCreateModelMixin, CommonUpdateModelMixin):
    queryset = IDC.objects.all()
    serializer_class = IDCSerializer
    authentication_classes = [LoginAuthentication, ]
    pagination_class = PageNumberPagination


# 主机分组 增删查改
class ServerGroupView(GenericViewSet, CommonListModelMixin, CommonRetrieveModelMixin, CommonDestroyModelMixin,
                      CommonCreateModelMixin, CommonUpdateModelMixin):
    queryset = ServerGroup.objects.all()
    serializer_class = ServerGroupSerializer
    authentication_classes = [LoginAuthentication, ]
    pagination_class = PageNumberPagination


# 凭据管理增删查改
class CredentialView(GenericViewSet, CommonListModelMixin, CommonRetrieveModelMixin, CommonDestroyModelMixin,
                     CommonCreateModelMixin, CommonUpdateModelMixin):
    queryset = Credential.objects.all()
    serializer_class = CredentialSerializer
    authentication_classes = [LoginAuthentication, ]
    pagination_class = PageNumberPagination


# 网络设备增删查改
class NetWorkServerView(GenericViewSet, CommonListModelMixin, CommonRetrieveModelMixin, CommonDestroyModelMixin,
                        CommonCreateModelMixin, CommonUpdateModelMixin):
    queryset = NetWorkServer.objects.all()
    serializer_class = NetWorkServerSerializer
    authentication_classes = [LoginAuthentication, ]
    pagination_class = PageNumberPagination


# 其他设备增删查改
class OtherMachineView(GenericViewSet, CommonListModelMixin, CommonRetrieveModelMixin, CommonDestroyModelMixin,
                       CommonCreateModelMixin, CommonUpdateModelMixin):
    queryset = OtherMachine.objects.all()
    serializer_class = OtherMachineSerializer
    authentication_classes = [LoginAuthentication, ]
    pagination_class = PageNumberPagination


# 物理机增删查改
from .libs.linux_ssh import SSH
from .libs.windows import Win_ssh
from django.conf import settings
import os
import json
from utils.common_response import APIResponse


class PhysicalServerView(GenericViewSet, CommonListModelMixin, CommonRetrieveModelMixin, CommonDestroyModelMixin,
                         CommonCreateModelMixin, CommonUpdateModelMixin):
    queryset = PhysicalServer.objects.all()
    serializer_class = PhysicalServerSerializer
    authentication_classes = [LoginAuthentication, ]
    pagination_class = PageNumberPagination

    @action(methods=['GET'], detail=True)
    def collect(self, request,*args,**kwargs):
        server_obj = self.get_object()
        machine_type = server_obj.machine_type
        # 判断机器类型，调用不同脚本执行
        if machine_type == 'linux':
            # 通过凭据ID获取用户名信息
            credential = Credential.objects.get(id=server_obj.credential_id)
            username = credential.username
            if credential.auth_mode == 1:
                password = credential.password
                ssh = SSH(server_obj.ssh_ip, server_obj.ssh_port, username, password=password)
            else:
                private_key = credential.private_key
                ssh = SSH(server_obj.ssh_ip, server_obj.ssh_port, username, key=private_key)

            test = ssh.test()  # 测试SSH连接通过
            if test['code'] == 200:
                client_agent_name = "collect_linux.py"
                local_file = os.path.join(settings.BASE_DIR, 'apps', 'cmdb', 'libs', 'file', client_agent_name)
                remote_file = os.path.join(settings.CLIENT_COLLECT_DIR, client_agent_name)  # 这个工作路径在setting里配置
                ssh.scp(local_file, remote_file=remote_file)
                ssh.command('chmod +x %s' % remote_file)
                result = ssh.command('python %s' % remote_file)
                # 采集脚本执行成功
                if result['code'] == 200:
                    data = json.loads(result['data'])
                    if server_obj.hostname != data['hostname']:
                        return APIResponse(msg='填写的主机名与目标主机不一致，请核对后再提交！')
                    code = 100
                    msg = '添加物理主机成功并同步配置'
                    data['is_verified'] = 'verified'
                    PhysicalServer.objects.filter(pk=server_obj.id).update(**data)
                else:
                    code = 101
                    msg = '采集物理主机配置失败！错误：%s' % result['msg']
            else:
                code = 101
                msg = 'SSH连接异常！错误：%s' % test['msg']
            return APIResponse(code=code, msg=msg)
        elif machine_type == 'windows':
            # 通过凭据ID获取用户名信息
            credential = Credential.objects.get(id=server_obj.credential_id)
            username = credential.username
            if credential.auth_mode == 1:
                password = credential.password
                win_ssh = Win_ssh(server_obj.ssh_ip, server_obj.ssh_port, username, password=password)
            else:
                code = 101
                msg = '填写的windows账号密码，没有key密钥保存连接方式, 请修改为账号密码连接方式。'
                return APIResponse(code=code, msg=msg)
            test = win_ssh.test()  # 测试SSH连接通过
            if test['code'] == 200:
                client_agent_name = "collect_windows.py"
                local_file = os.path.join(settings.BASE_DIR, 'apps', 'cmdb', 'libs', 'file', client_agent_name)
                remote_file = os.path.join(settings.CLIENT_COLLECT_WIN_DIR, client_agent_name)  # 这个工作路径在setting里配置
                win_ssh.win_scp(local_file, remote_file=remote_file)
                result = win_ssh.win_command('python %s' % remote_file)
                # 采集脚本执行成功
                if result['code'] == 200:
                    data = json.loads(result['data'])
                    if server_obj.hostname != data['hostname']:
                        code = 101
                        msg = '填写的主机名与目标主机不一致，请核对后再提交！'
                        return APIResponse(code=code, msg=msg)
                    code = 100
                    msg = '添加物理主机windows成功并同步配置'
                    data['is_verified'] = 'verified'
                    PhysicalServer.objects.filter(pk=server_obj.id).update(**data)
                    return APIResponse(code=code, msg=msg)
                else:
                    code = 101
                    msg = '采集物理主机windows配置失败！错误：%s' % result['msg']
            else:
                code = 102
                msg = 'windows SSH连接异常！错误：%s' % test['msg']
            return APIResponse(code=code, msg=msg)
